package sa4.routing

import scala.collection.mutable.HashMap
import sa4.sessions._
import sa4.templating._
import sa4.forms._
import sa4.css._
import sa4.Persistence._
import javax.servlet.http._
import scala.xml.PrettyPrinter
import java.net._
import scala.xml.XML
import scala.xml.NodeSeq
import scala.xml.Unparsed
import org.squeryl.PrimitiveTypeMode._
import org.squeryl.Schema
import org.squeryl.annotations.Column
import org.squeryl.KeyedEntity
import org.squeryl.annotations.OptionType
import org.squeryl.PrimitiveTypeMode._
import org.squeryl.KeyedEntity
import org.squeryl.dsl.ast.LogicalBoolean
import org.squeryl.annotations.OptionType
import scala.xml.Node
import scala.xml.Text

/*
 * A trait representing a singleton containing all functions called by their respective URIs.
 */
trait RoutingFunctions

/*
 * A singleton containing all functions called by their respective URIs with the GET method.
 */
object GETFunctions extends RoutingFunctions {

  def getWallReg(params: HashMap[String, String], req: HttpServletRequest, res: HttpServletResponse) {
    println(req.getLocalPort())
    if (sessionManager.sessionExist(req.getSession())) {
      res.sendRedirect("http://localhost:8080/theWall")
     // res.sendError(200);
    } else {
      val reg = scala.io.Source.fromFile("./html/wallregistration.html").mkString
      res.getWriter.write(reg)
    }
  }

  def getCss(params: HashMap[String, String], req: HttpServletRequest, res: HttpServletResponse) {
    var css = scala.io.Source.fromFile("./css/" + params("filePath") + ".css").mkString
    res.setHeader("Content-type", "text/css")
    res.getWriter.write(css)
  }

  def getJs(params: HashMap[String, String], req: HttpServletRequest, res: HttpServletResponse) {
    var js = scala.io.Source.fromFile("./javaScript/" + params("filePath") + ".js").mkString
    res.setHeader("Content-type", "application/x-javascript")
    res.getWriter.write(js)
  }

  def getBootstrap(params: HashMap[String, String], req: HttpServletRequest, res: HttpServletResponse) {
    var js = scala.io.Source.fromFile("./lib/bootstrap/js/" + params("filePath") + ".js").mkString
    res.setHeader("Content-type", "application/x-javascript")
    res.getWriter.write(js)
  }

  def getBricks(params: HashMap[String, String], req: HttpServletRequest, res: HttpServletResponse) = {

    var myWall: org.squeryl.Query[(String, String, Long)] = null
    transaction {
      val wall = from(WallDB.bricks, WallDB.users)((bricks, users) => where(bricks.userId === users.id) select (bricks.content, users.name, users.id))
      myWall = wall

      var resultWall = "<table class='table table-striped'><tbody> "
      var wallBrick = ""
      var i = 0
      for (x <- myWall) {
        i += 1
        wallBrick = "<tr><td><a class='btn btn-primary' id='post" + i + "-" + x._3 + "' rel='popover' data-original-title='Profile Data' onmouseover='showPopover(this.id)'>" + x._2 + "</a></td><td><em> " + x._1 + "</em></td></tr>" + wallBrick
      }
      resultWall += wallBrick + "</tbody></table>"

      res.getWriter.write(resultWall)
    }
  }

  def getUserData(params: HashMap[String, String], req: HttpServletRequest, res: HttpServletResponse) {
    val currentID = req.getParameter("userID").toLong
    transaction {
      val userData = from(WallDB.users)(user =>
        where(user.id === currentID)
          select (user.name, user.lastName, user.email))
      res.getWriter.write("<strong>First Name:</strong> " + userData.single._1 + "<br/>" +
        "<strong>Last Name:</strong> " + userData.single._2 + "<br/>" +
        "<strong>e-mail:</strong> " + userData.single._3)
    }
  }

  def render(username: String, content: NodeSeq) = {
    var list = content.map(tweet => <li> { Unparsed(tweet.text) } </li>)
    <html>
      <head>
        <title>feed list for { username } </title>
      </head>
      <body>
        <h1> feed list for <a href={ "http://twitter.com/" + username }> { username } </a></h1>
        <ul>{ list }</ul>
      </body>
    </html>
  }

}

object POSTFunctions extends RoutingFunctions {

  def getWallHomepage(params: HashMap[String, String], req: HttpServletRequest, res: HttpServletResponse) {
    var password = ""
    var email = ""
    var name = ""

    if (sessionManager.sessionExist(req.getSession())) {
      password = sessionManager.getAttribute("password")
      email = sessionManager.getAttribute("email")
    } else {
      password = req.getParameter("password")
      email = req.getParameter("email")
    }

    //  println(password, email)

    var found: Boolean = false
    var userID = 0L
    transaction {
      val result = from(WallDB.users)(user =>
        where(password === user.password and
          email === user.email)
          compute (count(user.id)))
      found = result.single.measures.intValue() >= 1

      val userName = from(WallDB.users)(user =>
        where(password === user.password and
          email === user.email)
          select (user.name, user.id))
      name = userName.single._1
      userID = userName.single._2

    }

    if (req.getParameter("rememberSession") == "on") {
      sessionManager.saveSession(req.getSession())
      sessionManager.saveAttribute("email", email)
      sessionManager.saveAttribute("password", password)

    }

    // creo una sessione con lo user
    if (found) {
      var result = parseTemplate.parse(<surround with="wall.html">{ name }<span id='userID' class='invisible'>{ userID }</span></surround>)
      res.getWriter.write(new PrettyPrinter(72, 2).formatNodes(fixQuotes(result)))
    }

  }

  def saveBrickOnDB(params: HashMap[String, String], req: HttpServletRequest, res: HttpServletResponse) {

  }

  def fixQuotes(template: NodeSeq): NodeSeq = {
    import scala.xml.transform._
    object FixQuotes extends BasicTransformer {
      override protected def unchanged(n: Node, ns: Seq[Node]) = ns.length == 1 && (ns.head eq n)
      override def transform(n: Node): Seq[Node] = n match {
        case n: Text => new Unparsed(n.text)
        case n => super.transform(n)
      }
    }
    FixQuotes.transform(template)
  }

  def registerUser(params: HashMap[String, String], req: HttpServletRequest, res: HttpServletResponse) {

    transaction {

      WallDB.users.insert(new User(req.getParameter("name"), req.getParameter("surname"), req.getParameter("email"), req.getParameter("password")))
    }

    var result = parseTemplate.parse(<surround with="registrationSuccesful.html">{ req.getParameter("name") }</surround>)
    res.getWriter.write(new PrettyPrinter(72, 2).formatNodes(result))

  }

  def postBrick(params: HashMap[String, String], req: HttpServletRequest, res: HttpServletResponse) {

    println(req.getParameter("content"))
    println(req.getParameter("userID"))
    transaction {
      WallDB.bricks.insert(new Brick(req.getParameter("content"), req.getParameter("userID").toLong))

      for (brick <- WallDB.bricks) {
        println("USER: " + brick.userId + " - CONTENT: " + brick.content)
      }
    }

  }

}



